home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Disc to the Future 2
/
Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin
/
MAC
/
THINKC
/
4_0
/
VIVIDUS
/
QD3D.SIT
/
qd3d
/
hedra.c
< prev
next >
Wrap
Text File
|
1991-10-09
|
6KB
|
280 lines
/* ======================================================================
Cqd3dPort primitive three dimensional routine library.
This is part of the qd3d Vividus Source Code Library. See the
extern qd3d.doc documentation file for usage. See individual
routines for routine documentation.
Copyright 1991 by Vividus Consulting.
This is not public domain source code. You may not copy and
paste from this source code. Read your Vividus Licensing
agreement for details and other restrictions.
Note: At present, HedraIntersect is not supported.
====================================================================== */
#include <Cqd3dPort.h>
#include <geometry.h>
#include "hedra.h"
#include <math.h>
#define abs(n) ((n < 0) ? -n : n)
#define min(a,b) ((a < b) ? a : b)
#define max(a,b) ((a > b) ? a : b)
extern Cqd3dPort *the3dPort;
static int hedraVN = 0;
static vector *hedraVerts = NULL;
static FixedVector *hedraVFdc = NULL;
static int hedraCN = 0;
static int hedraCL = 0;
static int *hedraConn = NULL;
static int *hedraCWrk = NULL;
/* ======================================================================
Usage: Use HedraConn and HedraVerts to set the current hedra. For
data format and general discussion see qd3d.doc.
Note:
This is library is not optimized to take advantage of hedraVFdc
or hedraCWrk. Use of those variables as intended will make this
library MUCH faster
====================================================================== */
void
HedraVerts(int n, vector wc[], FixedVector fdc[])
/*
Identifes the n vertices in wc (WC) to be used is subsequent calls to
hedra. Fdc is client supplied workspace for the n vertices. Fdc must
not be tampered with after the initial HedraVerts call.
*/
{
hedraVN = n;
hedraVerts = wc;
hedraVFdc = fdc;
}
void
HedraConn(int faces, int connLen, int connArray[], int connWrk[])
/*
Identifies the connArray (connectivity array) of length connLen and
faces for the subsequent hedra operations. connWrk is client supplied
workspace of length connLen.
*/
{
hedraCN = faces;
hedraCL = connLen;
hedraConn = connArray;
hedraCWrk = connWrk;
}
void
HedraFrame(void)
/*
Frames the n polygons of the current hedra. The framing color and
mode is the current foreground color and mode.
*/
{
int i;
vector verts[PolyMaxN];
int *q = hedraConn;
int v, oldq;
int j;
for (i = 0; i < hedraCN; i++) {
j = 0;
do {
v = abs (*q);
vcopy(&hedraVerts[v], &verts[j]);
j++;
oldq = *q++;
} while (oldq >= 0);
Poly3dFrame(j, verts);
}
}
void
HedraFrameErase(void)
/*
Erases the Frames of the n polygons of the current hedra
*/
{
int i;
vector verts[PolyMaxN];
int *q = hedraConn;
int v, oldq;
int j;
for (i = 0; i < hedraCN; i++) {
j = 0;
do {
v = abs (*q);
vcopy(&hedraVerts[v], &verts[j]);
j++;
oldq = *q++;
} while (oldq >= 0);
Poly3dFrameErase(j, verts);
}
}
void
HedraFill(
void (*color)(int face, vector *WCNorm)
)
/*
Fills and colors the polygons identified by the current hedra.
Color() is a user supplied coloring function. For each polygon identified in
the connectivity array, color() is called with the index of the face to be
colored and the normal of that face. It must set the pencolor to the
appropriate color.
*/
{
int i;
vector verts[PolyMaxN];
int *q = hedraConn;
int v, oldq;
int j;
vector facetColor;
vector norm;
for (i = 0; i < hedraCN; i++) {
j = 0;
do {
v = abs (*q);
vcopy(&hedraVerts[v], &verts[j]);
j++;
oldq = *q++;
} while (oldq >= 0);
vnorm(verts, &norm);
(*color) (i, &norm);
Poly3dFill(j, verts);
}
}
void
HedraErase(void)
/*
Erases the polygons identified by the current hedra.
*/
{
int i;
vector verts[PolyMaxN];
int *q = hedraConn;
int v, oldq;
int j;
for (i = 0; i < hedraCN; i++) {
j = 0;
do {
v = abs (*q);
vcopy(&hedraVerts[v], &verts[j]);
j++;
oldq = *q++;
} while (oldq >= 0);
Poly3dErase(j, verts);
}
}
Boolean
HedraIntersect(
Ray *r,
double *t,
int *face,
vector *faceNormal,
vector *facePt
)
/*
HedraIntersect returns true if the indicated ray intersects
the current hedra. If it does intersect, the ray parameter
t, the face index, faceNormal, and facePt parameters are
appropriately set.
If the ray intersects the hedra in multiple locations, only the
closest intersection will be returned.
NOTE: At present, this routine is unsupported.
*/
{
int i;
vector verts[PolyMaxN];
int *q = hedraConn;
int v, oldq;
int j;
Plane p;
vector xPoint, xNorm, tPoint;
int xFace;
double t1 = -1.0,
t2 = -1.0;
for (i = 0; i < hedraCN; i++) { /* Have to test every face. */
j = 0;
do {
v = abs (*q);
vcopy(&hedraVerts[v], &verts[j]);
j++;
oldq = *q++;
} while (oldq >= 0);
vnorm(verts, &p.normal);
vcopy(&verts[0], &p.pt);
if (RayXPlane(r, &p, &t2, &tPoint)) {
if (PtInPoly(&tPoint, j, verts, &p.normal))
if ((t2 > t1) || (t1 < 0.0)) {
t1 = t2;
xFace = i;
vcopy(&p.normal, &xNorm);
vcopy(&tPoint, &xPoint);
}
}
}
if (t1 > 0.000001) {
*t = t1;
*face = xFace;
vcopy(&xNorm, faceNormal);
vcopy(&xPoint, facePt);
return (true);
} else
return(false);
}
void Hedra2dBBox(Rect *r)
/*
This routine returns the 2d quickdraw rectangle bounding the current
hedra.
Note: The returned rectangle doesn't consider pen width.
*/
{
long i;
Point pt;
vector p;
TransformProject(1, &hedraVerts[0], &p);
pt.h = p.x;
pt.v = p.y;
SetRect(r, pt.h, pt.v, pt.h, pt.v);
for (i = 1; i < hedraVN; i++) {
TransformProject(1, &hedraVerts[i], &p);
pt.h = p.x;
pt.v = p.y;
r->top = min(r->top, pt.v);
r->left = min(r->left, pt.h);
r->right = max(r->right, pt.h);
r->bottom = max(r->bottom, pt.v);
}
}